﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Activities;
using System.Collections.ObjectModel;
using System.IO;
using System.Xml;
using System.Text.RegularExpressions;

namespace TfsExtensions.Build.Activities
{
    public sealed class UpdateSandcastleConfigFile : CodeActivity
    {
        [RequiredArgument]
        public InArgument<string> WorkingFolderName { get; set; }

        [RequiredArgument]
        public InArgument<string> SandcastlePresentationFolder { get; set; }

        [RequiredArgument]
        public InArgument<string> SandcastleConfigFilename { get; set; }

        [RequiredArgument]
        public InArgument<string> XPathFindCommentsData { get; set; }

        [RequiredArgument]
        public InArgument<string> XPathFindComments { get; set; }

        [RequiredArgument]
        public InArgument<Collection<string>> CommentXmlList { get; set; }
        // If your activity returns a value, derive from CodeActivity<TResult>
        // and return the value from the Execute method.
        protected override void Execute(CodeActivityContext context)
        {
            var sandcastlePresentationFolder = this.SandcastlePresentationFolder.Get(context);
            var workingFolderName = this.WorkingFolderName.Get(context);
            var sandcastleConfigFilename = this.SandcastleConfigFilename.Get(context);
            var xpathFindCommentsData = this.XPathFindCommentsData.Get(context);
            var xpathFindComments = this.XPathFindComments.Get(context);
            
            var sandcastleConfigFilePath = string.Format(@"{0}\configuration\{1}", sandcastlePresentationFolder, sandcastleConfigFilename);
            try
            {
                var destPath = string.Format(@"{0}\{1}", workingFolderName, sandcastleConfigFilename);
                if (File.Exists(sandcastleConfigFilePath))
                {
                    File.Copy(sandcastleConfigFilePath, destPath, true);
                }

                if(!File.Exists(destPath))
                {
                    LogHelper.LogMessage(context, "Sandcastle config file not found in " + destPath);
                    return;
                }

                var fileContents = File.ReadAllText(destPath);
                XmlDocument doc = new XmlDocument();
                doc.LoadXml(fileContents);
                XmlNode root = doc.DocumentElement;
                XmlNode nodeToRemove = root.SelectSingleNode(xpathFindCommentsData);
                if (nodeToRemove != null)
                {
                    var parentNode = nodeToRemove.ParentNode;
                    parentNode.RemoveChild(nodeToRemove);

                    var xmlFilesList = this.CommentXmlList.Get(context);

                    if (xmlFilesList != null)
                    {
                        foreach (var xmlFile in xmlFilesList)
                        {
                            var newNode = doc.CreateNode(XmlNodeType.Element, "data", null);
                            var xa = doc.CreateAttribute("files");
                            xa.Value = string.Format(@"{0}", xmlFile);
                            newNode.Attributes.Append(xa);
                            parentNode.AppendChild(newNode);
                        }
                    }
                    
                    doc.Save(destPath);

                    var contents = File.ReadAllText(destPath);
                    var regEx = new Regex(@".\\reflection.xml");

                    if (regEx.IsMatch(contents))
                    {
                        contents = regEx.Replace(contents, string.Format(@"{0}\reflection.xml", workingFolderName));
                    }

                    regEx = new Regex(@".\\Output\\html", RegexOptions.IgnoreCase);
                    if (regEx.IsMatch(contents))
                    {
                        contents = regEx.Replace(contents, string.Format(@"{0}\html", workingFolderName));
                    }

                    regEx = new Regex("base=\".\\\\Sandcastle\\\\Data\\\\Reflection\"", RegexOptions.IgnoreCase);

                    if (regEx.IsMatch(contents))
                    {
                        var replaceText = "base=\"" + workingFolderName + "\"";
                        contents = regEx.Replace(contents, replaceText);
                    }

                    File.WriteAllText(destPath, contents);
                }
            }
            catch(Exception ex)
            {
                LogHelper.LogError(context, ex.Message);
                throw;
            }
        }
    }
}
